#include <iostream>
#include "simulator/tools/bitTools.h"
#include "dspSimulator/dspSimulator/dspSimulator.h"

using namespace dspsimulator;
using namespace simulator;

int main() {
    auto dsp_machine = std::make_shared<DspMachine>();
    std::shared_ptr<LLVMJit> llvmJit = std::make_shared<LLVMJit>();
    const char *filePath = "/home/zengao/Desktop/dsp-sim/for.out";
    std::shared_ptr<simulator::ELF32Loader> elfLoader = std::make_shared<simulator::ELF32Loader>(filePath);

    auto dsp_simulator = std::make_shared<dspsimulator::DSPSimulator>(dsp_machine, llvmJit, elfLoader);

    std::string pc_name = get_reg_name(dspsimulator::RegKind::PC);
    u32 pc = 0x85A4;
    dsp_machine->registers()->get_reg32(pc_name)->set_data(pc);
    auto memory = dsp_machine->mmu()->memory();
    // 0400A358 MVK .L1  0,A8
    {
        std::vector<u8> mvk = {0x58, 0xa3, 0x00, 0x04};
        memory->write(mvk, pc);
        pc += 4;
    }
    // 0084a358 MVK .L1  1,A1
    {
        std::vector<u8> mvk = {0x58, 0xa3, 0x84, 0x00};
        memory->write(mvk, pc);
        pc += 4;
    }
    // 8083a001 [A1] SPLOOPD 2
    {
        std::vector<u8> sploopd = {0x01, 0xa0, 0x83, 0x80};
        memory->write(sploopd, pc);
        pc += 4;
    }
    // 06a013a2 mvc a8,ILC
    {
        std::vector<u8> mvc = {0xa2, 0x13, 0xa0, 0x06};
        memory->write(mvc, pc);
        pc += 4;
    }
    // 04202940 add 1,a8,a8
    {
        std::vector<u8> add = {0x40, 0x29, 0x20, 0x04};
        memory->write(add, pc);
        pc += 4;
    }
    // 0c6e NOP 1
    {
        std::vector<u8> nop = {0x6e, 0x0c};
        memory->write(nop, pc);
        pc += 2;
    }
    // 0c6e NOP 1
    {
        std::vector<u8> nop = {0x6e, 0x0c};
        memory->write(nop, pc);
        pc += 2;
    }
    // .fphead E8000000
    {
        std::vector<u8> headword = {0x00, 0X00, 0X00, 0xe8};
        std::cout << "headword " << common::dec_to_hex(pc) << std::endl;
        memory->write(headword, pc);
        pc += 4;
    }
    // 08034001 SPKERNEL 1, 0
    {
        std::vector<u8> spkernel = {0X01, 0x40,0X03,0X08};
        memory->write(spkernel, pc);
        pc += 4;
    }
    // 039c2058 add 1,a7,a7
    {
        std::vector<u8> add = {0x58, 0x20, 0x9c, 0x03};
        memory->write(add, pc);
        pc += 4;
    }
    // 00004000 nop
    {
        std::vector<u8> nop = {0x00, 0X00, 0x00, 0x00};
        memory->write(nop, pc);
        pc += 4;
    }
    // 00004000 nop
    {
        std::vector<u8> nop = {0x00, 0X00, 0x00, 0x00};
        memory->write(nop, pc);
        pc += 4;
    }
    // 00004000 nop
    {
        std::vector<u8> nop = {0x00, 0X00, 0x00, 0x00};
        memory->write(nop, pc);
        pc += 4;
    }
    dsp_simulator->run();
}